package com.senthink.gl.business.area;

import com.senthink.gl.business.common.entity.PageDto;
import com.senthink.gl.business.common.entity.SearchRequest;
import com.senthink.gl.business.common.exception.BusinessException;
import com.senthink.gl.business.common.util.RandomUtils;
import com.senthink.gl.business.domain.entity.Area;
import com.senthink.gl.business.domain.service.AreaDataService;
import com.senthink.gl.business.domain.service.UserAreaAuthorityDataService;
import com.senthink.gl.business.messages.CodeMsg;
import com.senthink.gl.business.response.ApiResponse;
import com.senthink.gl.business.response.CodeMsgDataResponse;
import com.senthink.gl.business.security.SecurityUtils;
import com.senthink.gl.business.userlog.SystemUserLog;
import com.senthink.gl.business.userlog.enums.LogDetailEnum;
import com.senthink.gl.business.userlog.enums.LogOperateEnum;
import com.senthink.gl.business.userlog.enums.LogTypeEnum;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.domain.Page;
import org.springframework.data.domain.PageImpl;
import org.springframework.data.domain.PageRequest;
import org.springframework.data.domain.Sort;
import org.springframework.stereotype.Service;

import java.util.LinkedList;
import java.util.List;

/**
 * 区域服务
 *
 * @author zooqi@senthink.com
 * @date 2017/11/30
 */
@Service
public class AreaService {

    @Autowired
    private CodeMsg codeMsg;
    @Autowired
    private AreaDataService dataService;
    @Autowired
    private UserAreaAuthorityDataService areaAuthorityDataService;


    /**
     * 获取区域详情
     *
     * @param areaRequest
     * @return
     */
    public ApiResponse getDetailByAid(AreaRequest areaRequest) {
        Area area = dataService.findByAid(areaRequest.getAid())
                .orElseThrow(() -> new BusinessException(codeMsg.recordNotFoundCode(), codeMsg.recordNotFoundMsg()));

        AreaNewResponse areaResponse = new AreaNewResponse();
        BeanUtils.copyProperties(area, areaResponse);

        return new CodeMsgDataResponse(codeMsg.successCode(), codeMsg.successMsg(), areaResponse);
    }

    /**
     * 添加区域
     *
     * @param areaRequest
     * @return
     */
    @SystemUserLog(operate = LogOperateEnum.CREATE, detail = LogDetailEnum.CREATE_AREA, logType = LogTypeEnum.AREA)
    public ApiResponse save(AreaRequest areaRequest) {
        // 校验名字
        if (dataService.countByName(areaRequest.getName()) != 0) {
            throw new BusinessException(codeMsg.nameExistCode(), codeMsg.nameExistMsg());
        }

        Area area = new Area();
        BeanUtils.copyProperties(areaRequest, area);
        area.setAid(RandomUtils.randomString(30));

        return new CodeMsgDataResponse(codeMsg.successCode(), codeMsg.successMsg(), dataService.save(area));
    }

    /**
     * 删除区域
     *
     * @param request
     * @return
     */
    @SystemUserLog(operate = LogOperateEnum.DELETE, detail = LogDetailEnum.DELETE_AREA, logType = LogTypeEnum.AREA)
    public ApiResponse delete(AreaRequest request) {
        if (dataService.deleteByAid(request.getAid())) {
            return new CodeMsgDataResponse(codeMsg.successCode(), codeMsg.successMsg());
        }
        return new CodeMsgDataResponse<>(codeMsg.recordNotFoundCode(), codeMsg.recordNotFoundMsg());
    }

    /**
     * 更新区域信息
     *
     * @param areaRequest
     * @return
     */
    @SystemUserLog(operate = LogOperateEnum.UPDATE, detail = LogDetailEnum.UPDATE_AREA, logType = LogTypeEnum.AREA)
    public ApiResponse update(AreaRequest areaRequest) {
        Area oldArea = dataService.findByAid(areaRequest.getAid())
                .orElseThrow(() -> new BusinessException(codeMsg.recordNotFoundCode(), codeMsg.recordNotFoundMsg()));
        // 忽略大小写
        if (!oldArea.getName().equalsIgnoreCase(areaRequest.getName())) {
            if (dataService.countByName(areaRequest.getName()) != 0) {
                throw new BusinessException(codeMsg.nameExistCode(), codeMsg.nameExistMsg());
            }
        }

        Area newArea = new Area();
        BeanUtils.copyProperties(oldArea, newArea);
        BeanUtils.copyProperties(areaRequest, newArea);
        return new CodeMsgDataResponse(codeMsg.successCode(), codeMsg.successMsg(), dataService.save(newArea));
    }

    /**
     * 获取所有区域列表(按区域名称排序)
     *
     * @return
     */
    public ApiResponse findAll(String account) {
        Sort sort = new Sort("name");

        List<Area> list;
        if (SecurityUtils.isRoot()) {
            list = dataService.findAll(sort);
        } else {
            list = areaAuthorityDataService.findAreasByAccount(account);
        }

        return new CodeMsgDataResponse(codeMsg.successCode(), codeMsg.successMsg(), list);
    }

    /**
     * 分页+筛选+搜索区域列表
     *
     * @param pageDto       分页参数
     * @param searchRequest 搜索参数
     * @return
     */
    public ApiResponse findAll(PageDto pageDto, SearchRequest searchRequest) {
        PageRequest pageRequest = pageDto.convertToPageRequestOrderByTime();
        Page<Area> page = dataService.findAll(pageRequest, searchRequest);

        List<AreaResponse> list = new LinkedList<>();
        for (Area area : page.getContent()) {
            AreaResponse areaResponse = new AreaResponse();
            BeanUtils.copyProperties(area, areaResponse);
            areaResponse.setUsers(areaAuthorityDataService.findUserNamesByArea(area));
            list.add(areaResponse);
        }
        Page<AreaResponse> response = new PageImpl<>(list, pageRequest, page.getTotalElements());
        return new CodeMsgDataResponse(codeMsg.successCode(), codeMsg.successMsg(), response);
    }
}
